package com.androidxmpp;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.database.ContentObserver;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.util.DisplayMetrics;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.ExpandableListView;
import android.widget.ExpandableListView.OnChildClickListener;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

import com.androidxmpp.adapter.UserListAdapter;
import com.androidxmpp.config.PreferenceConstants;
import com.androidxmpp.db.RosterProvider;
import com.androidxmpp.db.RosterProvider.RosterConstants;
import com.androidxmpp.fragment.FragmentCallBack;
import com.androidxmpp.fragment.RecentChatFragment;
import com.androidxmpp.fragment.SettingsFragment;
import com.androidxmpp.model.Roster;
import com.androidxmpp.receiver.XMPPBroadcastReceiver;
import com.androidxmpp.receiver.XMPPBroadcastReceiver.EventHandler;
import com.androidxmpp.service.IConnectionStatusCallback;
import com.androidxmpp.service.XMPPService;
import com.androidxmpp.ui.ActionItem;
import com.androidxmpp.ui.QuickAction;
import com.androidxmpp.ui.QuickAction.OnActionItemClickListener;
import com.androidxmpp.ui.SlidingMenu;
import com.androidxmpp.util.LogUtil;
import com.androidxmpp.util.NetUtil;
import com.androidxmpp.util.PreferenceUtils;
import com.androidxmpp.util.ToastUtil;
import com.androidxmpp.util.XMPPHelper;

public class MainActivity extends BaseSlidingFragmentActivity implements
		IConnectionStatusCallback, EventHandler, OnClickListener,
		FragmentCallBack {

	private final Activity activity = this;

	// 用户在线状态
	private static final int ID_CHAT = 0;
	private static final int ID_AVAILABLE = 1;
	private static final int ID_AWAY = 2;
	private static final int ID_XA = 3;
	private static final int ID_DND = 4;
	public static HashMap<String, Integer> mStatusMap;
	static {
		mStatusMap = new HashMap<String, Integer>();
		mStatusMap.put(PreferenceConstants.OFFLINE, -1);
		mStatusMap.put(PreferenceConstants.DND, R.drawable.status_shield);
		mStatusMap.put(PreferenceConstants.XA, R.drawable.status_invisible);
		mStatusMap.put(PreferenceConstants.AWAY, R.drawable.status_leave);
		mStatusMap.put(PreferenceConstants.AVAILABLE, R.drawable.status_online);
		mStatusMap.put(PreferenceConstants.CHAT, R.drawable.status_qme);
	}

	// view
	private TextView ivTitleName;// 用户名
	private ImageView ivTitleStatus;// 在线状态
	private ProgressBar ivTitleProgress;// 加载用户信息
	private LinearLayout net_status_bar_top;
	private ImageButton btn_left;
	private ImageButton btn_right;

	private ExpandableListView ex_user_list;// 好友列表
	private TextView empty;
	private ContentObserver mRosterObserver = new RosterObserver();// 轮询获取列表信息
	private UserListAdapter userListAdapter;
	private SlidingMenu mSlidingMenu;

	//
	private Handler mHandler = new Handler();
	private XMPPService xmppService;

	// 启动XMPP服务
	private ServiceConnection mServiceConnection = new ServiceConnection() {

		@Override
		public void onServiceDisconnected(ComponentName name) {
			xmppService.unRegisterConnectionStatusCallback();
			xmppService = null;
		}

		@Override
		public void onServiceConnected(ComponentName name, IBinder service) {
			xmppService = ((XMPPService.XMPPBinder) service).getService();// 绑定service
			xmppService.registerComponentCallbacks(MainActivity.this);

			// 判断是否掉线
			if (!xmppService.isAuthenticated()) {
				String account = PreferenceUtils.getPrefString(activity,
						PreferenceConstants.ACCOUNT, "");
				String password = PreferenceUtils.getPrefString(activity,
						PreferenceConstants.PASSWORD, "");

				xmppService.Login(account, password);// 重新自动登录
			} else {
				ivTitleName.setText(XMPPHelper
						.splitJidAndServer(PreferenceUtils.getPrefString(
								activity, PreferenceConstants.ACCOUNT, "")));
				setStatusImage(true);
				ivTitleProgress.setVisibility(View.GONE);
			}
		}
	};

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.act_main_center);
		initSlidingMenu();
		initView();
	}

	private void initSlidingMenu() {
		DisplayMetrics dm = new DisplayMetrics();
		getWindowManager().getDefaultDisplay().getMetrics(dm);
		int mScreenWidth = dm.widthPixels;// 获取屏幕分辨率宽度
		setBehindContentView(R.layout.main_left_layout);// 设置左菜单
		FragmentTransaction mFragementTransaction = getSupportFragmentManager()
				.beginTransaction();
		Fragment mFrag = new RecentChatFragment();
		mFragementTransaction.replace(R.id.main_left_fragment, mFrag);
		mFragementTransaction.commit();
		// customize the SlidingMenu
		mSlidingMenu = getSlidingMenu();
		mSlidingMenu.setMode(SlidingMenu.LEFT_RIGHT);// 设置是左滑还是右滑，还是左右都可以滑，我这里左右都可以滑
		mSlidingMenu.setShadowWidth(mScreenWidth / 40);// 设置阴影宽度
		mSlidingMenu.setBehindOffset(mScreenWidth / 8);// 设置菜单宽度
		mSlidingMenu.setFadeDegree(0.35f);// 设置淡入淡出的比例
		mSlidingMenu.setTouchModeAbove(SlidingMenu.TOUCHMODE_MARGIN);
		mSlidingMenu.setShadowDrawable(R.drawable.shadow_left);// 设置左菜单阴影图片
		mSlidingMenu.setSecondaryShadowDrawable(R.drawable.shadow_right);// 设置右菜单阴影图片
		mSlidingMenu.setFadeEnabled(true);// 设置滑动时菜单的是否淡入淡出
		mSlidingMenu.setBehindScrollScale(0.333f);// 设置滑动时拖拽效果
	}

	/**
	 * 初始化控件
	 */
	private void initView() {

		mSlidingMenu.setSecondaryMenu(R.layout.main_right_layout);
		FragmentTransaction mFragementTransaction = getSupportFragmentManager()
				.beginTransaction();
		Fragment mFrag = new SettingsFragment();
		mFragementTransaction.replace(R.id.main_right_fragment, mFrag);
		mFragementTransaction.commit();
		btn_left = (ImageButton) findViewById(R.id.show_left_fragment_btn);
		btn_right = (ImageButton) findViewById(R.id.show_right_fragment_btn);
		btn_left.setVisibility(View.VISIBLE);
		btn_right.setVisibility(View.VISIBLE);
		btn_left.setOnClickListener(this);
		btn_right.setOnClickListener(this);

		ivTitleName = (TextView) findViewById(R.id.ivTitleName);
		ivTitleStatus = (ImageView) findViewById(R.id.ivTitleStatus);
		ivTitleProgress = (ProgressBar) findViewById(R.id.ivTitleProgress);
		net_status_bar_top = (LinearLayout) findViewById(R.id.net_status_bar_top);
		net_status_bar_top.setVisibility(View.GONE);

		ivTitleName.setText(XMPPHelper.splitJidAndServer(PreferenceUtils
				.getPrefString(activity, PreferenceConstants.ACCOUNT, "")));
		ivTitleName.setOnClickListener(this);

		ex_user_list = (ExpandableListView) findViewById(R.id.ex_user_list);
		empty = (TextView) findViewById(R.id.empty);
		userListAdapter = new UserListAdapter(activity);
		ex_user_list.setAdapter(userListAdapter);
		userListAdapter.requery();

		ex_user_list.setOnItemLongClickListener(new OnItemLongClickListener() {

			@Override
			public boolean onItemLongClick(AdapterView<?> parent,
					View convertView, int position, long index) {

				return false;
			}
		});

		ex_user_list.setOnChildClickListener(new OnChildClickListener() {

			@Override
			public boolean onChildClick(ExpandableListView parent, View v,
					int groupPosition, int childPosition, long id) {
				Roster roster = userListAdapter.getChild(groupPosition,
						childPosition);
				String userJid = roster.getJid();// 用户的id
				String userName = roster.getAlias();// 用户名称

				// 点击聊天界面
				Intent intent = new Intent(activity, ChatActivity.class);
				Uri userNameUri = Uri.parse(userJid);
				intent.setData(userNameUri);
				intent.putExtra(ChatActivity.INTENT_EXTRA_USERNAME, userName);
				startActivity(intent);
				overridePendingTransition(R.anim.enteralpha, R.anim.exitalpha);
				return false;
			}
		});
	}

	private static final String[] GROUPS_QUERY = new String[] {
			RosterConstants._ID, RosterConstants.GROUP, };
	private static final String[] ROSTER_QUERY = new String[] {
			RosterConstants._ID, RosterConstants.JID, RosterConstants.ALIAS,
			RosterConstants.STATUS_MODE, RosterConstants.STATUS_MESSAGE, };

	public List<String> getRosterGroups() {
		// we want all, online and offline
		List<String> list = new ArrayList<String>();
		Cursor cursor = getContentResolver().query(RosterProvider.GROUPS_URI,
				GROUPS_QUERY, null, null, RosterConstants.GROUP);
		int idx = cursor.getColumnIndex(RosterConstants.GROUP);
		cursor.moveToFirst();
		while (!cursor.isAfterLast()) {
			list.add(cursor.getString(idx));
			cursor.moveToNext();
		}
		cursor.close();
		return list;
	}

	public List<String[]> getRosterContacts() {
		// we want all, online and offline
		List<String[]> list = new ArrayList<String[]>();
		Cursor cursor = getContentResolver().query(RosterProvider.CONTENT_URI,
				ROSTER_QUERY, null, null, RosterConstants.ALIAS);
		int JIDIdx = cursor.getColumnIndex(RosterConstants.JID);
		int aliasIdx = cursor.getColumnIndex(RosterConstants.ALIAS);
		cursor.moveToFirst();
		while (!cursor.isAfterLast()) {
			String jid = cursor.getString(JIDIdx);
			String alias = cursor.getString(aliasIdx);
			if ((alias == null) || (alias.length() == 0))
				alias = jid;
			list.add(new String[] { jid, alias });
			cursor.moveToNext();
		}
		cursor.close();
		return list;
	}

	/**
	 * 获取用户在线状态
	 * 
	 * @param isConnected
	 *            连接状态
	 */
	private void setStatusImage(boolean isConnected) {
		if (!isConnected) {
			ivTitleStatus.setVisibility(View.GONE);
			return;
		}

		String statusMode = PreferenceUtils.getPrefString(activity,
				PreferenceConstants.STATUS_MODE, PreferenceConstants.AVAILABLE);
		int status = mStatusMap.get(statusMode);
		if (status == -1) {
			ivTitleStatus.setVisibility(View.GONE);
		} else {
			ivTitleStatus.setVisibility(View.VISIBLE);
			ivTitleStatus.setImageResource(status);
		}

	}

	@Override
	public void onNetChange() {

	}

	@Override
	public void connectionStatusChanged(int connectedState, String reason) {

	}

	@Override
	public void onClick(View v) {
		switch (v.getId()) {
		case R.id.show_left_fragment_btn:
			mSlidingMenu.showMenu(true);
			break;

		case R.id.show_right_fragment_btn:

			mSlidingMenu.showSecondaryMenu(true);

			break;

		case R.id.ivTitleName:

			if (isConnected()) {
				showStatusQuickAction(v);
			}

			break;

		case R.id.net_status_bar_top:
			Intent intent = new Intent("android.settings.SETTINGS");
			startActivity(intent);

			break;

		default:
			break;
		}
	}

	/**
	 * 改变用户在线状态
	 */
	private void showStatusQuickAction(View v) {
		QuickAction quickAction = new QuickAction(this, QuickAction.VERTICAL);
		quickAction.addActionItem(new ActionItem(ID_CHAT,
				getString(R.string.status_chat), getResources().getDrawable(
						R.drawable.status_qme)));
		quickAction.addActionItem(new ActionItem(ID_AVAILABLE,
				getString(R.string.status_available), getResources()
						.getDrawable(R.drawable.status_online)));
		quickAction.addActionItem(new ActionItem(ID_AWAY,
				getString(R.string.status_away), getResources().getDrawable(
						R.drawable.status_leave)));
		quickAction.addActionItem(new ActionItem(ID_XA,
				getString(R.string.status_xa), getResources().getDrawable(
						R.drawable.status_invisible)));
		quickAction.addActionItem(new ActionItem(ID_DND,
				getString(R.string.status_dnd), getResources().getDrawable(
						R.drawable.status_shield)));
		quickAction
				.setOnActionItemClickListener(new OnActionItemClickListener() {

					@Override
					public void onItemClick(QuickAction source, int pos,
							int actionId) {
						// TODO Auto-generated method stub
						if (!isConnected()) {
							ToastUtil.showShort(MainActivity.this,
									R.string.conversation_net_error_label);
							return;
						}
						switch (actionId) {
						case ID_CHAT:
							ivTitleStatus
									.setImageResource(R.drawable.status_qme);
							PreferenceUtils.setPrefString(MainActivity.this,
									PreferenceConstants.STATUS_MODE,
									PreferenceConstants.CHAT);
							PreferenceUtils.setPrefString(MainActivity.this,
									PreferenceConstants.STATUS_MESSAGE,
									getString(R.string.status_chat));
							break;
						case ID_AVAILABLE:
							ivTitleStatus
									.setImageResource(R.drawable.status_online);
							PreferenceUtils.setPrefString(MainActivity.this,
									PreferenceConstants.STATUS_MODE,
									PreferenceConstants.AVAILABLE);
							PreferenceUtils.setPrefString(MainActivity.this,
									PreferenceConstants.STATUS_MESSAGE,
									getString(R.string.status_available));
							break;
						case ID_AWAY:
							ivTitleStatus
									.setImageResource(R.drawable.status_leave);
							PreferenceUtils.setPrefString(MainActivity.this,
									PreferenceConstants.STATUS_MODE,
									PreferenceConstants.AWAY);
							PreferenceUtils.setPrefString(MainActivity.this,
									PreferenceConstants.STATUS_MESSAGE,
									getString(R.string.status_away));
							break;
						case ID_XA:
							ivTitleStatus
									.setImageResource(R.drawable.status_invisible);
							PreferenceUtils.setPrefString(MainActivity.this,
									PreferenceConstants.STATUS_MODE,
									PreferenceConstants.XA);
							PreferenceUtils.setPrefString(MainActivity.this,
									PreferenceConstants.STATUS_MESSAGE,
									getString(R.string.status_xa));
							break;
						case ID_DND:
							ivTitleStatus
									.setImageResource(R.drawable.status_shield);
							PreferenceUtils.setPrefString(MainActivity.this,
									PreferenceConstants.STATUS_MODE,
									PreferenceConstants.DND);
							PreferenceUtils.setPrefString(MainActivity.this,
									PreferenceConstants.STATUS_MESSAGE,
									getString(R.string.status_dnd));
							break;
						default:
							break;
						}
						xmppService.setStatusFromConfig();
					}
				});
		quickAction.show(v);
	}

	@Override
	protected void onResume() {
		super.onResume();
		// 绑定serVice
		bindXMPPService();
		getContentResolver().registerContentObserver(
				RosterProvider.CONTENT_URI, true, mRosterObserver);
		XMPPBroadcastReceiver.mListeners.add(this);
		userListAdapter.requery();
		setStatusImage(isConnected());
		if (!isConnected())
			ivTitleName.setText(R.string.login_prompt_no);
		if (NetUtil.getNetworkState(this) == NetUtil.NETWORN_NONE)
			net_status_bar_top.setVisibility(View.VISIBLE);
		else
			net_status_bar_top.setVisibility(View.GONE);

	}

	@Override
	protected void onPause() {
		super.onPause();

		getContentResolver().unregisterContentObserver(mRosterObserver);
		unbindXMPPService();
		XMPPBroadcastReceiver.mListeners.remove(this);
	}

	private void unbindXMPPService() {
		try {
			unbindService(mServiceConnection);
			LogUtil.i(LoginActivity.class, "[SERVICE] Unbind");
		} catch (IllegalArgumentException e) {
			LogUtil.e(LoginActivity.class, "Service wasn't bound!");
		}
	}

	private void bindXMPPService() {
		LogUtil.i(LoginActivity.class, "[SERVICE] Unbind");
		bindService(new Intent(MainActivity.this, XMPPService.class),
				mServiceConnection, Context.BIND_AUTO_CREATE
						+ Context.BIND_DEBUG_UNBIND);
	}

	private boolean isConnected() {
		return xmppService != null && xmppService.isAuthenticated();
	}

	public void updateRoster() {
		userListAdapter.requery();
	}

	private class RosterObserver extends ContentObserver {
		public RosterObserver() {
			super(mHandler);
		}

		public void onChange(boolean selfChange) {
			LogUtil.d(MainActivity.class, "RosterObserver.onChange: "
					+ selfChange);
			if (userListAdapter != null)
				mHandler.postDelayed(new Runnable() {
					public void run() {
						updateRoster();
					}
				}, 100);
		}
	}

	long l = 0;

	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		// TODO Auto-generated method stub
		if (keyCode == KeyEvent.KEYCODE_BACK
				&& event.getAction() == KeyEvent.ACTION_DOWN) {
			if ((System.currentTimeMillis() - l) > 2000) {
				Toast.makeText(getApplicationContext(), "再按一次退出程序",
						Toast.LENGTH_SHORT).show();
				l = System.currentTimeMillis();
			} else {
				overridePendingTransition(R.anim.enteralpha, R.anim.exitalpha);
				finish();
			}
			return true;
		}
		return super.onKeyDown(keyCode, event);
	}

	@Override
	public XMPPService getService() {
		return xmppService;
	}

	@Override
	public MainActivity getMainActivity() {
		return this;
	}

}
